require.config({
    paths: {
        'sortable': "../addons/fastflow/plugins/sortable/sortable.min",
    },
});
define(['jquery', 'sortable', 'form'], function ($, Sortable, Form) {

    var FormBuilder = {
        widgetContentId: null,
        customformContentId: null,
        widgetSortable: null,
        customformSortable: null,
        multipleTypes: ['selectpicker', 'selectpage', 'userSelectpage', 'adminSelectpage', 'categorySelectpage', 'image', 'file'],
        decimalTypes: ['inputNumber'],
        optionsTypes: ['radio', 'checkbox', 'selectpicker'],
        datasourceTypes: ['selectpage'],
        nonredundantTypes: ['userSelectpage', 'adminSelectpage', 'categorySelectpage'],
        immutableSelectpageTypes: ['userSelectpage', 'adminSelectpage', 'categorySelectpage'],
        defaultValue: {},
        formData: {
            sort: [],
            widget: []
        },
        currentWidgetId: null,
        create: function (widgetContentId, customformContentId) {
            FormBuilder.widgetContentId = widgetContentId;
            FormBuilder.customformContentId = customformContentId;
            FormBuilder.initSortable(widgetContentId, customformContentId);
        },
        initSortable: function (widgetContentId, customformContentId) {
            var widgetContent = document.getElementById(widgetContentId);

            var widgetContentOption = {
                animation: 200,
                draggable: ".widget",
                sort: false,
                forceFallback: true,
                filter: function (evt, item) {
                    if ($.inArray($(item).data('type'), FormBuilder.nonredundantTypes) !== -1) {
                        for (var i = 0; i < FormBuilder.formData.widget.length; i++) {
                            if (FormBuilder.formData.widget[i].type === $(item).data('type')) {
                                return true;
                            }
                        }
                    }
                },
                group: {
                    name: 'widgetContent',
                    pull: 'clone',
                    put: false
                },
                onStart: function (evt) {

                },
                onEnd: function (evt) {
                    if (evt.pullMode === 'clone') {
                        var widget = $(evt.item);

                        FormBuilder.addTrashBtn(widget);
                        FormBuilder.trashBindevent(widget);
                        FormBuilder.addData(widget);
                        FormBuilder.widgetBindevent(widget);

                        if ($.inArray(widget.data('type'), FormBuilder.nonredundantTypes) !== -1) {
                            $(evt.clone).addClass('no-drag');
                        }

                        $('#' + FormBuilder.customformContentId).trigger('widget-clone');
                        Form.api.bindevent(widget);
                    }
                },
                onClone: function (evt) {

                }
            };
            FormBuilder.widgetSortable = Sortable.create(widgetContent, widgetContentOption);

            var customformContent = document.getElementById(customformContentId);
            var customformContentOption = {
                animation: 200,
                draggable: ".widget",
                group: {
                    name: "customformContent",
                    pull: true,
                    put: true
                },
                onStart: function (evt) {
                },
                onEnd: function (evt) {
                },
                onUpdate: function (evt) {
                    FormBuilder.updateSort(FormBuilder.customformSortable.toArray());
                    $('#' + FormBuilder.customformContentId).trigger('sortable-update');
                }
            };
            FormBuilder.customformSortable = Sortable.create(customformContent, customformContentOption);
        },
        addTrashBtn: function (widget) {
            var trashHtml = '<a href="javascript:;" class="widget-trash text-danger pull-right hidden"><i class="fa fa-close"></i></a>';
            widget.append(trashHtml);
        },
        trashBindevent: function (widget) {
            FormBuilder.trashOver(widget);
            FormBuilder.trashClick(widget);
        },
        widgetBindevent: function (widget) {
            FormBuilder.widgetClick(widget);
        },
        changeIdName: function (widget) {
            widget.attr('data-id', FormBuilder.getRandId(10));
            var type = widget.data('type');
            if (type === 'radio' || type === 'checkbox') {
                var randName = FormBuilder.getRandId(8);
                widget.find('.checkbox,.radio').find('label').each(function (index, element) {
                    var randID = FormBuilder.getRandId(8);
                    $(element).attr('for', randID);
                    $('input', element).attr('id', randID).attr('name', 'row[' + randName + ']');
                });
            }
        },
        getRandId: function (length) {
            return Number(Math.random().toString() + Date.now()).toString(36).substr(3, length);
        },
        getRandName: function(length){
            var str = 'abcdefghijklmnopqrstuvwxyz';
            var name = '';
            for (var i = length; i > 0; --i)
                name += str[Math.floor(Math.random() * str.length)];
            return name;
        },
        updateSort: function (sort) {
            FormBuilder.formData.sort = sort;
        },
        addWidgetData: function (widget) {
            var type = widget.data('type');
            var data = {
                id: widget.data('id'),
                type: widget.data('type'),
                name: FormBuilder.getRandName(8),
                title: widget.data('title'),
                defaultValue: ''
            };
            if ($.inArray(type, FormBuilder.decimalTypes) !== -1) {
                data.decimal = 0;
            }
            if ($.inArray(type, FormBuilder.optionsTypes) !== -1) {
                data.options = [{key: 'a', value: 'A'}, {key: 'b', value: 'B'}];
                data.defaultValue = 'a';
            }
            if ($.inArray(type, FormBuilder.datasourceTypes) !== -1) {
                data.datasource = data.name.replaceAll('_','/') + '/index';
            }
            if ($.inArray(type, FormBuilder.multipleTypes) !== -1) {
                data.multiple = 1;
            }
            if ($.inArray(type, FormBuilder.immutableSelectpageTypes) !== -1) {
                data.name = type.replace('Selectpage','') + '_id';
            }
            FormBuilder.formData.widget.push(data);
        },
        addData: function (widget) {
            FormBuilder.changeIdName(widget);
            FormBuilder.addWidgetData(widget);
            FormBuilder.updateSort(FormBuilder.customformSortable.toArray());
        },
        removeWidget: function (widget) {
             var widgetId = widget.data('id');
            for (var i = 0; i < FormBuilder.formData.widget.length; i++) {
                if (FormBuilder.formData.widget[i].id === widgetId) {
                    FormBuilder.formData.widget.splice(i, 1);
                    break;
                }
            }
            for (var k = 0; k < FormBuilder.formData.sort.length; k++) {
                if (FormBuilder.formData.sort[k] === widgetId) {
                    FormBuilder.formData.sort.splice(k, 1);
                    break;
                }
            }
            if ($.inArray(widget.data('type'), FormBuilder.nonredundantTypes) !== -1) {
                $('div[data-type="' + widget.data('type') + '"]').removeClass('no-drag');
            }
            widget.remove();
        },
        widgetClick: function (widget) {
            $(widget).click(function () {
                $('.widget').removeClass('widgetActive');
                $(this).addClass('widgetActive');
                FormBuilder.currentWidgetId = $(this).data('id');
                var widgetData = null;
                for (var i = 0; i < FormBuilder.formData.widget.length; i++) {
                    if ($(this).data('id') === FormBuilder.formData.widget[i].id) {
                        widgetData = FormBuilder.formData.widget[i];
                        break;
                    }
                }
                $('#' + FormBuilder.customformContentId).trigger('widget-click', widgetData);
            });
        },
        trashClick: function (widget) {
            $('.widget-trash', widget).click(function () {
                FormBuilder.removeWidget(widget);
                $('#' + FormBuilder.customformContentId).trigger('widget-remove', widget);
            });
        },
        trashOver: function (widget) {
            $(widget).mouseover(function () {
                $('.widget-trash', widget).removeClass('hidden');
            });
            $(widget).mouseleave(function () {
                $('.widget-trash', widget).addClass('hidden');
            });
        },
        clearData: function () {
            FormBuilder.formData.sort = [];
            FormBuilder.formData.widget = [];
            FormBuilder.currentWidgetId = null;
            for (var i = 0; i < FormBuilder.nonredundantTypes.length; i++) {
                $('div[data-type="' + FormBuilder.nonredundantTypes[i] + '"]').removeClass('no-drag');
            }

        },
        setData: function (id, data) {
            var keys = Object.keys(data);
            var index = 0;
            for (var i = 0; i < FormBuilder.formData.widget.length; i++) {
                if (id === FormBuilder.formData.widget[i].id) {
                    index = i;
                    break;
                }
            }
            var widgetData = FormBuilder.formData.widget[index];
            keys.forEach(function (item) {
                widgetData[item] = data[item];
            });
            if ($.inArray(widgetData.type, FormBuilder.immutableSelectpageTypes) !== -1) {
                widgetData.name = widgetData.multiple == 1 ? widgetData.type.replace('Selectpage','') + '_id' : widgetData.type.replace('Selectpage','') + '_ids';
            }
            if ($.inArray(widgetData.type, FormBuilder.datasourceTypes) !== -1) {
                widgetData.datasource = widgetData.name.replaceAll('_','/') + '/index';
            }
        },
        getData: function (id) {
            for (var i = 0; i < FormBuilder.formData.widget.length; i++) {
                if (id === FormBuilder.formData.widget[i].id) {
                    return FormBuilder.formData.widget[i];
                }
            }
        },
    };
    return FormBuilder;
});